import 'package:flutter/foundation.dart';
import 'package:flutter_provider_demo/commons/http_client.dart';
import 'package:flutter_provider_demo/config/environment.dart';
import 'package:logger/logger.dart';

abstract class ILog {
  void debug(String message);
  void info(String message);
  void warn(String message, [dynamic error, StackTrace? stackTrace]);
  void error(String message, [dynamic error, StackTrace? stackTrace]);
  void fatal(String message, [dynamic error, StackTrace? stackTrace]);
}

class Log extends ILog {
  static final Log _instance = Log._();
  factory Log() => _instance;
  Log._() {
    if (kDebugMode) {
      _logger = Logger(
        printer: SimplePrinter(
          printTime: true,
        ),
      );
    } else {
      _logger = Logger(
        printer: SimplePrinter(),
        output: CrashlyticsOutput(),
      );
    }
  }

  late Logger _logger;

  @override
  void debug(String message) {
    if (kDebugMode) {
      _logger.d(message);
    }
  }

  @override
  void info(String message) {
    if (kDebugMode) {
      _logger.i(message);
    }
  }

  @override
  void warn(String message, [error, StackTrace? stackTrace]) {
    _logger.w(message, error: error, stackTrace: stackTrace);
  }

  @override
  void error(String message, [error, StackTrace? stackTrace]) {
    _logger.e(message, error: error, stackTrace: stackTrace);
  }

  @override
  void fatal(String message, [error, StackTrace? stackTrace]) {
    _logger.f(message, error: error, stackTrace: stackTrace);
  }
}

class CrashlyticsOutput extends LogOutput {
  final HttpClient _client = HttpClient();

  @override
  void output(OutputEvent event) {
    switch (event.level) {
      case Level.error:
      case Level.fatal:
        _client.post(
          '${Env.apiBaseUrl}/log',
          body: {"lines": event.lines},
        );
        break;
      default:
        _client.post(
          '${Env.apiBaseUrl}/log',
          body: {"lines": event.lines},
        );
    }
  }
}
